package com.controller;

import com.content.DoctorTime;
import com.model._do.AppointmentDO;
import com.model._do.SignUpDO;
import com.model.dto.AppointResultDTO;
import com.model.dto.EquipAppointDTO;
import com.model.dto.baseDTO.ResultDTO;
import com.service.AppointmentService;
import com.service.EquipmentService;
import com.service.ResultService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/appoint")
public class AppointmentController {

    @Autowired
    private AppointmentService appointmentService;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private ResultService resultService;

    /**
     * 根据id将perform置为1
     * @param appoint id
     * @return 成功提示
     */
    @RequestMapping("/doConfirmAppoint")
    public ResultDTO doConfirmAppoint(@RequestBody AppointmentDO appoint){
        try{
            appointmentService.doConfirmAppoint(appoint);
            return resultService.createSuccess("success");
        } catch (Exception e){
            return resultService.createFailed("failed");
        }

    }

    /**
     * 根据id将perform置为0，
     * @param appoint id
     * @return 成功提示
     */
    @RequestMapping("/doConfirmOverAppoint")
    public ResultDTO doConfirmOverAppoint(@RequestBody AppointmentDO appoint){
        try{
            appointmentService.doConfirmOverAppoint(appoint);
            return resultService.createSuccess("success");
        } catch (Exception e){
            return resultService.createFailed("failed");
        }
    }

    /**
     * 根据appoint将对应的agreement置为1
     * @param appoint id，er or ed
     * @return 成功提示
     */
    @RequestMapping("/doAgreeAppoint")
    public ResultDTO doAgreeAppoint(@RequestBody AppointmentDO appoint){
        appointmentService.doAgreeAppoint(appoint);
        return resultService.createSuccess("success");
    }

    /**
     * 根据appointId将edAgreement or doAgreement置为0
     * @param appoint id
     * @return 成功提示
     */
    @RequestMapping("/doRejectAppoint")
    public ResultDTO edCancelAppoint(@RequestBody AppointmentDO appoint){
        try{
            appointmentService.doRejectAppoint(appoint);
            return resultService.createSuccess("success");
        } catch (Exception e){
            return resultService.createFailed("failed");
        }

    }

    /**
     * 患者侧根据userId获取与我签约的所有equip以及未来两天时间内他们的非无效预约
     * @param sign userId
     * @return List {List appoint，Equipment equip}
     */
    @RequestMapping(value = "/getMyAppoint", method = RequestMethod.POST)
    public ResultDTO getMyAppoint(@RequestBody SignUpDO sign){
        List<EquipAppointDTO> relateList = equipmentService.getEquipDoctorRelate(sign);
        return resultService.createSuccess("success", relateList);
    }

    /**
     * 根据id获取appoint 双方最近两日公共可用时间
     * @param appoint 实体1id， 实体2id
     * @return List appoint
     */
    @RequestMapping(value = "/getEntityAviliTime", method = RequestMethod.POST)
    public ResultDTO getDoctorAviliTime(@RequestBody AppointmentDO appoint){
        List<AppointmentDO> untime = appointmentService.getEntityUnAviliTime(appoint);
        List<Date> aviliTimeList = DoctorTime.getTimeList();
        return resultService.createSuccess("success" ,filterAviliTime(untime, aviliTimeList));
    }

    /**
     * 根据equipId，userId增加新的appoint，
     * @param appointment 新appoint
     * @return 成功提示
     */
    @RequestMapping(value = "/doAppointmentEquDoc", method = RequestMethod.POST)
    public ResultDTO doAppointEquDoc(@RequestBody AppointmentDO appointment){
        appointmentService.doAppointmentEquDoc(appointment);
        return resultService.createSuccess("success");
    }

    private List<AppointResultDTO> filterAviliTime(List<AppointmentDO> untime, List<Date> aviliTimeList){
        HashMap<String, Date> hashMap = new HashMap();
        aviliTimeList.forEach(date -> hashMap.put(date.toString(), date));
        for (AppointmentDO appoint: untime
             ) {
            Date currentDate = appoint.getAppointmentTime();
            Calendar currentCalendar = Calendar.getInstance();
            currentCalendar.setTime(currentDate);
            currentCalendar.set(Calendar.MINUTE, 0);
            currentCalendar.set(Calendar.SECOND,0);

            if(hashMap.get(currentCalendar.getTime().toString())!= null ){
                hashMap.remove(currentCalendar.getTime().toString());
            } else {
                currentCalendar.add(Calendar.HOUR_OF_DAY, -1);
                if(hashMap.get(currentCalendar.getTime().toString()) != null){
                    hashMap.remove(currentCalendar.getTime().toString());
                }
            }
        }
        List<AppointResultDTO> resultList = hashMap.keySet().stream().map(key -> new AppointResultDTO(hashMap.get(key))).collect(Collectors.toList());
        resultList.sort(Comparator.comparing(AppointResultDTO::getTime));
        return resultList;
    }
}
